package com.jichaoyun.sys.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jichaoyun.common.enums.MyExceptiontType;
import com.jichaoyun.common.ex.MyException;
import com.jichaoyun.model.entity.Role;
import com.jichaoyun.model.entity.StationInfo;

import com.jichaoyun.common.model.Result;
import com.jichaoyun.model.entity.Valve;
import com.jichaoyun.model.entity.User;
import com.jichaoyun.model.vo.UserRegVo;
import com.jichaoyun.model.vo.UserVo;
import com.jichaoyun.sys.mapper.RoleMapper;
import com.jichaoyun.sys.mapper.StationInfoMapper;
import com.jichaoyun.sys.mapper.UserMapper;
import com.jichaoyun.sys.mapper.ValveMapper;
import com.jichaoyun.sys.service.IStationInfoService;
import com.jichaoyun.sys.service.IUserService;
import com.jichaoyun.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private StationInfoMapper stationInfoMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private IStationInfoService stationInfoService;

    @Autowired
    private ValveMapper valveInfoMapper;


    /**
     * 用户注册
     * @param reg
     */
    @Override
    public void reg(UserRegVo reg) {
        String username = reg.getUsername();

        //mbp按单一字段查表 username -> user
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,username);
        User result = this.baseMapper.selectOne(wrapper);

        if (result != null) {
            throw new MyException(MyExceptiontType.DUPLICATEUSERNAME,null);
        }
        String salt = UUID.randomUUID().toString().toUpperCase();
        String md5Password = getMd5Password(reg.getPassword(), salt);

        User user = new User();
        user.setUsername(username);
        user.setPassword(md5Password);
        user.setUserRole(reg.getUserRole());
        user.setSalt(salt);
        user.setParentId(reg.getNowUserId());
        user.setCompanyName(reg.getCompanyName());
        user.setTel(reg.getTel());
        user.setCreatedTime(new Timestamp(System.currentTimeMillis()));
        user.setPrincipal(reg.getPrincipal());
        user.setPwdChange(reg.getPwdChange());
        user.setNameChange(reg.getNameChange());

        // 判断受影响的行数是否不为1，则抛出InsertException异常
        Integer rows = userMapper.insert(user);
        if (rows != 1) {
            throw new MyException(MyExceptiontType.Other,"添加数据异常，请联系管理员");
        }
        //对蒸汽站进行处理
        for(Integer num : reg.getSteamStationNos()){
            if(stationInfoService.getById(num) != null){
                StationInfo stationInfo = new StationInfo();
                stationInfo.setAppUserId(user.getId());
                stationInfo.setStationNo(num);
                stationInfoMapper.updateById(stationInfo);
            }else{
                throw new MyException(MyExceptiontType.STATIONNOTFIND,null);
            }
        }

//        //对水的站进行处理
//        for(Integer num : reg.getWaterStationNos()){
//            if(stationInfoMapper.selectOneWaterStation(num)!= null){
//                stationInfoMapper.updateOneWaterStation(num,user.getId());
//            }else{
//                throw new MyException(MyExceptiontType.STATIONNOTFIND,null);
//            }
//        }
    }
    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    @Override
    public User login(String username, String password) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,username);
        User result = this.baseMapper.selectOne(wrapper);

        if (result == null) {
            throw new MyException(MyExceptiontType.USERNOTFIND,null);
        }
        if (result.getStatus().equals(0)) {
            throw new MyException(MyExceptiontType.USERNOTENABLE,null);
        }
        Role role = this.roleMapper.selectById(result.getUserRole());
        if(!role.getStatus()){
            throw new MyException(MyExceptiontType.ROLENOTENABLE,null);
        }

        // 从查询结果中获取盐值，将参数password和salt结合起来进行加密
        String salt = result.getSalt();
        String md5Password = getMd5Password(password, salt);
        if (!result.getPassword().equals(md5Password)) {
            throw new MyException(MyExceptiontType.PASSWORDNOTMATCH,null);
        }

        //更新最近登录时间
        result.setLastloginTime(LocalDateTime.now());
        this.baseMapper.updateById(result);

        // 创建新的User对象，将查询结果中的uid、username、avatar封装到新的user对象中
        User user = new User();
        user.setId(result.getId());
        user.setUsername(result.getUsername());
        user.setUserRole(result.getUserRole());
        user.setCompanyName(result.getCompanyName());
        user.setCreatedTime(result.getCreatedTime());
        user.setBalance(result.getBalance());
        user.setPrincipal(result.getPrincipal());
        user.setStatus(result.getStatus());
        user.setPwdChange(result.getPwdChange());
        user.setNameChange(result.getNameChange());
        return user;
    }

    /**
     * 分页获取所有用户信息
     * @param pageNo
     * @return
     */
    @Override
    public IPage<User> getUserList(Integer pageNo) {
        IPage<User> userIPage = new Page<>(pageNo,10);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("id");


        return userMapper.selectPage(userIPage,queryWrapper);
    }

    /**
     * 获取所有用户信息
     * @return
     */
    @Override
    public List<User> getUserList() {
;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("id");


        return userMapper.selectList(queryWrapper);
    }

    /**
     * 更改用户密码
     * @param id
     * @param password
     */
    @Override
    public Result<Object> updatePassword(Integer id, String password) {


        if(password == null){
            throw new MyException(MyExceptiontType.PASSWORDNOTALLOWEDNULL,null);
        }
        User user = this.getById(id);
        String new_password = getMd5Password(password,user.getSalt());
        user.setPassword(new_password);

        userMapper.updateById(user);
        return Result.success("修改成功");
    }

    /**
     * 停用/启用 用户
     * @param id
     */
    @Override
    public Result<Object> updateStatus(Integer id) {

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId,id);
        User result = this.baseMapper.selectOne(wrapper);
        if (result == null) {
            throw new MyException(MyExceptiontType.USERNOTFIND,null);
        }

        if(result.getStatus().equals(1)){
            result.setStatus(0);
        } else if (result.getStatus().equals(0)) {
            result.setStatus(1);
        }

        userMapper.updateById(result);
        return Result.success("修改成功");
    }

    /**
     * 用户修改
     * @param reg
     */
    @Override
    public void updateUserInfo(UserRegVo reg) {
        Integer id = reg.getId();

        //把原用户拥有的蒸汽站点置空
        LambdaQueryWrapper<StationInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StationInfo::getAppUserId,id);
        List<StationInfo> stationInfoList = stationInfoMapper.selectList(queryWrapper);
        for(StationInfo stationInfo:stationInfoList){
            stationInfo.setAppUserId(-1);
            this.stationInfoMapper.updateById(stationInfo);
        }

//        //把原用户拥有的水站点置空
//        List<StationInfo> stationInfoList1 = stationInfoMapper.selectWaterStationsByUid(id);
//        for(StationInfo stationInfo:stationInfoList1){
//            this.stationInfoMapper.updateOneWaterStation(stationInfo.getStationNo(),-1);
//        }

        //mbp按单一字段查表 id -> user
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId,id);
        User result = this.baseMapper.selectOne(wrapper);
        result.setUsername(reg.getUsername());
        result.setUserRole(reg.getUserRole());
        result.setParentId(reg.getNowUserId());
        result.setCompanyName(reg.getCompanyName());
        result.setTel(reg.getTel());
        result.setPrincipal(reg.getPrincipal());
        result.setPwdChange(reg.getPwdChange());
        result.setNameChange(reg.getNameChange());
        userMapper.update(result, wrapper);

        if(reg.getSteamStationNos()!=null){
            //对蒸汽站进行处理
            for(Integer num : reg.getSteamStationNos()){
                if(stationInfoService.getById(num) != null){
                    StationInfo stationInfo = new StationInfo();
                    stationInfo.setAppUserId(id);
                    stationInfo.setStationNo(num);
                    stationInfoMapper.updateById(stationInfo);
                }else{
                    throw new MyException(MyExceptiontType.STATIONNOTFIND,null);
                }
            }
        }

//        if(reg.getWaterStationNos()!=null){
//            //对水的站进行处理
//            for(Integer num : reg.getWaterStationNos()){
//                if(stationInfoMapper.selectOneWaterStation(num)!= null){
//                    stationInfoMapper.updateOneWaterStation(num,id);
//                }else{
//                    throw new MyException(MyExceptiontType.STATIONNOTFIND,null);
//                }
//            }
//        }

    }

    /**
     * 删除用户
     * @param id 用户ID
     * @return 删除结果
     */
    @Override
    public Result<Object> deleteUserById(Integer id) {
        try {
            User user1 = userMapper.selectById(id);
            if (user1==null){
                return Result.fail("此用户不存在，已经删除");
            }
            // 处理站点信息
            LambdaQueryWrapper<StationInfo> stationQueryWrapper = new LambdaQueryWrapper<>();
            stationQueryWrapper.eq(StationInfo::getAppUserId, id);
            List<StationInfo> stationInfoList = this.stationInfoMapper.selectList(stationQueryWrapper);

            // 检查是否存在站点信息
            if (stationInfoList.size()!=0) {
                for (StationInfo stationInfo : stationInfoList) {
                    stationInfo.setAppUserId(null);
                    this.stationInfoMapper.updateById(stationInfo);
                }
            }

            // 处理阀门信息
            LambdaQueryWrapper<Valve> valveQueryWrapper = new LambdaQueryWrapper<>();

            valveQueryWrapper.eq(Valve::getUserName, user1.getUsername());
            List<Valve> valveInfoList = this.valveInfoMapper.selectList(valveQueryWrapper);

            // 检查是否存在阀门信息
            if (valveInfoList.size()!=0) {
                return Result.fail("删除失败，该用户绑定阀门管理员，请更换管理员后再试！！");
            }

            // 删除用户信息
            int i = userMapper.deleteById(id);
            if(i==1){
                return Result.success("删除用户成功");
            }else{
                return Result.fail("出现异常");
            }


        } catch (MyException e) {
            // 抛出删除用户失败的自定义异常
            throw new MyException(MyExceptiontType.DELETINGUSERERROR, null);
        }
    }

    /**
     * 获取所有用户的id及对应name
     * @return
     */
    @Override
    public Result<List<Map<String, Object>>> getallUserIdAndUserName(){
        List<Map<String, Object>> userList = new ArrayList<>();

        // 使用MyBatis Plus的QueryWrapper来查询所有用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeleted, 0);
        queryWrapper.eq(User::getStatus, 1);
        List<User> allUsers = userMapper.selectList(queryWrapper);

        for (User user : allUsers) {
            Map<String, Object> userData = new HashMap<>();
            userData.put("id",  user.getId());
            userData.put("name", user.getUsername());
            userList.add(userData);
        }

        return Result.success(userList);

    }

    /**
     * APP中的模糊搜索，下拉用户选项框
     *
     * @param likeName
     * @return
     */
    @Override
    public List<String> getUserNameListByLikeName(String likeName) {
        if(likeName == null){
            likeName = "";
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(User::getUsername,likeName).eq(User::getDeleted,0);
        List<User> userList = userMapper.selectList(wrapper);

        ArrayList<String> res = new ArrayList<>();
        for (User user : userList) {
            res.add(user.getUsername());
        }
        return res;
    }

    /**
     * 根据用户名称获取用户的信息
     * @param username
     * @return
     */
    @Override
    public User getByName(String username) {
        LambdaQueryWrapper<User> wp = new LambdaQueryWrapper<>();
        wp.eq(User::getUsername,username.trim());
        User user = userMapper.selectOne(wp);
        return user;
    }

    /**
     * 根据token获取用户信息
     * @param token
     * @return
     */
    @Override
    public UserVo getUserInfo(String token) {
        token = "Bearer " + token;
        return JwtUtil.verifyJwtToken(token);
    }

    /**
     * 通过用户id获得其拥有的站号
     * @param id
     * @return
     */
    @Override
    public List<Integer> getSteamStationNosByUid(Integer id) {
        LambdaQueryWrapper<StationInfo> wp = new LambdaQueryWrapper<>();
        wp.eq(StationInfo::getAppUserId,id);
        List<StationInfo> stationInfoList = stationInfoMapper.selectList(wp);
        List<Integer> resList= new ArrayList<>();
        for (StationInfo stationInfo : stationInfoList) {
            resList.add(stationInfo.getStationNo());
        }

        return resList;
    }

    @Override
    @DS("water")
    public List<Integer> getWaterStationNosByUid(Integer id) {
        LambdaQueryWrapper<StationInfo> wp = new LambdaQueryWrapper<>();
        wp.eq(StationInfo::getAppUserId,id);
        List<StationInfo> stationInfoList = stationInfoMapper.selectList(wp);
        List<Integer> resList= new ArrayList<>();
        for (StationInfo stationInfo : stationInfoList) {
            resList.add(stationInfo.getStationNo());
        }

        return resList;
    }



    //todo 修改密码

    //todo 登出


    /**
     * 执行密码加密 使用UUID作为盐值，在原始密码的左右两侧拼接，循环加密3次
     *
     * @param password 原始密码
     * @param salt     盐值
     * @return 加密后的密文
     */
    public String getMd5Password(String password, String salt) {
        for (int i = 0; i < 3; i++) {
            password = DigestUtils.md5DigestAsHex((salt + password +
                    salt).getBytes()).toUpperCase();
        }
        return password;
    }
}
